package com.dd; import com.intellij.ide.projectView.ViewSettings; import com.intellij.ide.util.PropertiesComponent; import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ProjectStructureProvider implements com.intellij.ide.projectView.TreeStructureProvider { public static final char COMPOSE_BY_CHAR = '_'; private static final String OTHER_NODE = "other"; @Nullable @Override public Object getData(Collection<AbstractTreeNode> collection, String s) { return null; } @NotNull @Override public Collection<AbstractTreeNode> modify(@NotNull AbstractTreeNode parent, @NotNull Collection<AbstractTreeNode> children, ViewSettings viewSettings) { List<AbstractTreeNode> resultList = new ArrayList<>(); if (parent.getValue() instanceof PsiDirectory) { PsiDirectory directory = (PsiDirectory) parent.getValue(); String path = directory.getVirtualFile().getPath(); if (SettingsManager.isComposed(path)) { resultList.addAll(createComposedFiles(children, viewSettings)); } else { resultList.addAll(children); } } else { resultList.addAll(children); } return resultList; } @NotNull private List<AbstractTreeNode> createComposedFiles(@NotNull Collection<AbstractTreeNode> fileNodes, ViewSettings viewSettings) { List<AbstractTreeNode> resultList = new ArrayList<>(); Project project = Utils.getCurrentProject(); if (project != null) { HashSet<String> composedDirNameSet = new HashSet<>(); List<AbstractTreeNode> notComposedFileNodes = new ArrayList<>(); final boolean customPrefix = PropertiesComponent.getInstance().getBoolean(SettingConfigurable.PREFIX_CUSTOM_USE, false); Pattern pattern = customPrefix ? Pattern.compile(PropertiesComponent.getInstance().getValue(SettingConfigurable.PREFIX_PATTERN, SettingConfigurable.DEFAULT_PATTERN)) : null; for (AbstractTreeNode fileNode : fileNodes) { if (fileNode.getValue() instanceof PsiFile) { PsiFile psiFile = (PsiFile) fileNode.getValue(); String fileName = psiFile.getName(); if (customPrefix) { Matcher m = pattern.matcher(fileName); if (m.find()) { String composedDirName = m.group(0); composedDirNameSet.add(composedDirName); } else { notComposedFileNodes.add(fileNode); } } else { int endIndex = fileName.indexOf(COMPOSE_BY_CHAR); if (endIndex != -1) { String composedDirName = fileName.substring(0, endIndex); composedDirNameSet.add(composedDirName); } else { notComposedFileNodes.add(fileNode); } } } } for (String composedDirName : composedDirNameSet) { List<AbstractTreeNode> composedFileNodes = filterByDirName(fileNodes, composedDirName); PsiFile psiFile = (PsiFile) composedFileNodes.get(0).getValue(); DirectoryNode composedDirNode = new DirectoryNode(project, viewSettings, psiFile, composedDirName); composedDirNode.addAllChildren(composedFileNodes); resultList.add(composedDirNode); } if (!notComposedFileNodes.isEmpty()) { PsiFile psiFile = (PsiFile) notComposedFileNodes.get(0).getValue(); DirectoryNode composedDirNode = new DirectoryNode(project, viewSettings, psiFile, OTHER_NODE); composedDirNode.addAllChildren(notComposedFileNodes); resultList.add(composedDirNode); } } return resultList; } @NotNull private List<AbstractTreeNode> filterByDirName(Collection<AbstractTreeNode> fileNodes, String token) { List<AbstractTreeNode> resultList = new ArrayList<>(); final boolean customPrefix = PropertiesComponent.getInstance().getBoolean(SettingConfigurable.PREFIX_CUSTOM_USE, false); Pattern pattern = customPrefix ? Pattern.compile(PropertiesComponent.getInstance().getValue(SettingConfigurable.PREFIX_PATTERN, SettingConfigurable.DEFAULT_PATTERN)) : null; for (AbstractTreeNode fileNode : fileNodes) { if (fileNode.getValue() instanceof PsiFile) { PsiFile psiFile = (PsiFile) fileNode.getValue(); String fileName = psiFile.getName(); if (customPrefix) { Matcher m = pattern.matcher(fileName); if (m.find()) { String composedDirName = m.group(0); if (composedDirName.equals(token)) { resultList.add(fileNode); } } } else { int endIndex = fileName.indexOf(COMPOSE_BY_CHAR); if (endIndex != -1) { String composedDirName = fileName.substring(0, endIndex); if (composedDirName.equals(token)) { resultList.add(fileNode); } } } } } return resultList; } }